package com.iclippi.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.iclippi.client.Editor.AutosaveHandler;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Clippy implements EntryPoint, ResizeHandler {

	private final ClipboardServiceAsync clipboardService = GWT
			.create(ClipboardService.class);

	private static Clippy singelton;
	private final MessagePanel messagePanel = MessagePanel.getInstance();
	private final Editor editor = new Editor();
	private TopPanel topPanel;
	private Timer reloadTimer;

	private long clipboardVersion;
	private String clipboardName;

	public static Clippy get() {
		return singelton;
	}

	public long getClipboardVersion() {
		return clipboardVersion;
	}

	public void setClipboardVersion(long clipboardVersion) {
		this.clipboardVersion = clipboardVersion;
	}

	private void setClipboardName(String clipboardName) {
		this.clipboardName = clipboardName;
	}

	private String getClipboardName() {
		return this.clipboardName;
	}

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		singelton = this;

		// Support history (#clipboardname tags) and history refreshs.
		// History tag is stronger then cookie.
		String historyToken = History.getToken();
		if (historyToken != "" && historyToken != null)
			clipboardName = historyToken;
		else {
			clipboardName = Cookies.getCookie("clipboardName");
			if (clipboardName == null) 
				clipboardName = "default";
		}

		reloadTimer = new Timer() {

			@Override
			public void run() {
				clipboardService.clipboardGetVersion(clipboardName,
						new AsyncCallback<Long>() {

							@Override
							public void onSuccess(Long version) {
								Long thisVersion = getClipboardVersion();
								if (version > thisVersion) {
									if (editor.getDirty()) {
										// Show clipboard is unsynced...
										messagePanel
												.showMessage("Unsynced!", 0);

									} else {
										loadClipboard(getClipboardName());
									}
								}
							}

							@Override
							public void onFailure(Throwable caught) {
								// Do nothing.
							}
						});
				// TODO Auto-generated method stub

			}
		};

		editor.addAutosaveHandler(new AutosaveHandler() {
			@Override
			public void onAutosave() {
				clipboardService.clipboardGetVersion(clipboardName,
						new AsyncCallback<Long>() {
							@Override
							public void onSuccess(Long version) {
								Long thisVersion = getClipboardVersion();
								if (version == thisVersion)
									if (editor.getDirty())
										saveClipboard(clipboardName);
							}

							@Override
							public void onFailure(Throwable caught) {
								// Do nothing.
							}
						});

			}
		});
		topPanel = new TopPanel(clipboardName);
		DockPanel outer = new DockPanel();
		outer.add(editor, DockPanel.CENTER);
		outer.add(topPanel, DockPanel.NORTH);

		Window.addResizeHandler(this);
		Window.enableScrolling(false);
		Window.setMargin("0px");

		RootPanel.get().add(outer);
		loadClipboard(clipboardName);

		// Read history changes and execute them
		History.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {
				String historyToken = event.getValue();

				if (historyToken != "" && historyToken != null) {
					loadClipboard(historyToken);
					topPanel.setClipboardName(historyToken);
				}
			}
		});

		DeferredCommand.addCommand(new Command() {
			public void execute() {
				adjustSize(Window.getClientWidth(), Window.getClientHeight());
				reloadTimer.scheduleRepeating(30000);
			}
		});

	}

	@Override
	public void onResize(ResizeEvent event) {
		adjustSize(event.getWidth(), event.getHeight());

	}

	public void adjustSize(int width, int height) {
		editor.adjustSize(width, height - topPanel.getOffsetHeight());
		topPanel.adjustSize(width, height);
		messagePanel.adjustSize();
	}

	public void loadClipboard(String clipboardName) {
		Cookies.setCookie("clipboardName", clipboardName);
		History.newItem(clipboardName);
		messagePanel.showMessage("Loading...", 0);

		clipboardService.clipboardLoad(clipboardName,
				new AsyncCallback<ClipboardLoadData>() {

					@Override
					public void onFailure(Throwable caught) {
						messagePanel.showMessage("Error loading - "
								+ caught.getMessage(), 15000);
					}

					@Override
					public void onSuccess(ClipboardLoadData clipboardLoadData) {
						editor.setEditorValue(clipboardLoadData.getContent());
						editor.setDirty(false);
						setClipboardName(clipboardLoadData.getName());
						setClipboardVersion(clipboardLoadData.getVersion());
						messagePanel.showMessage("Loaded!");
					}

				});
	}

	public void saveClipboard(String clipboardName) {
		String html = editor.getEditorValue();
		messagePanel.showMessage("Saving...", 0);
		clipboardService.clipboardSave(clipboardName, html,
				new AsyncCallback<Long>() {

					@Override
					public void onFailure(Throwable caught) {
						messagePanel.showMessage("Error saving - "
								+ caught.getMessage(), 15000);

					}

					@Override
					public void onSuccess(Long version) {
						messagePanel.showMessage("Saved!");
						setClipboardVersion(version);
						editor.setDirty(false);

					}

				});

	}

}
